//
// Created by haoy on 2017/3/13.
//

#ifndef RECORD_RTP_READER_HPP
#define RECORD_RTP_READER_HPP

#include <stdint.h>
#include <stdio.h>
#include <string>
#include <vector>

#include "dbg.hpp"
#include "media_hapi.h"
#include "packet.hpp"
#include "packet_reorder.hpp"
#include "rtp.h"
#include "timestamp.hpp"
#include "tlv.hpp"
#include "util.h"
#include "vpx/vpx_decoder.h"
#include "xdtls_srtp.h"


class TimeRange {
public:
    uint64_t from;
    uint64_t to;
};

// RTPReader, reads TLV format file and feed to handler
class RTPReader {
public:
    static const uint32_t BUF_SIZE = 1*1024*1024;

public:
    RTPReader();
    ~RTPReader();

    void input(const std::string& input_fn);
    void range(const std::list<TimeRange>& time_range);
    void audio(bool audio);
    void video(bool video);
    RTPReader& handler(PacketHandler* handler);
    RTPReader& time(const Timestamp& t);
    const Timestamp& time() const;
    void run();

private:
    void onCodec(uint8_t * buf, size_t len);
    void onSDP(uint8_t * buf, size_t len);
    void onSRTPKey(bool is_remote, uint8_t * buf, size_t len);  //bridge-xswitch
    void onSRTP(bool is_remote, uint8_t * buf, size_t len); //bridge-xswitch
    void onRTP(uint64_t& timestamps, uint8_t * buf, size_t len);
    void onRTCP(uint8_t * buf, size_t len);
    void onEnd();

    void next_time_range(uint64_t cur);

private:
    FILE* _input_fp;
    PacketHandler* _handler;

    uint8_t* _buf;

    CodecRegistry _codecs;
    Timestamp _timestamps;
    bool _time_set = false;

    PacketReorder<RTPPacket> _audio_reorder;
    PacketReorder<RTPPacket> _video_reorder;

    uint32_t _video_ssrc = 0;
    uint32_t _audio_ssrc = 0;
    uint32_t _audio_last_seq = 0;
    uint32_t _video_last_seq = 0;
    uint16_t _audio_cycles = 0;
    uint16_t _video_cycles = 0;

    RTPMap _rtp_map;

    TimeRange _cur_time_range;
    std::list<TimeRange> _time_ranges;
    bool _read_audio = true;
    bool _read_video = true;

    
    struct Channel {
        xdtls_srtp_t dtls = nullptr;
        bool ready = false;
    };

    std::map<int, Channel> _channels;
};
#endif //RECORD_RTP_READER_HPP
